package lz77;

import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import lz77.util.ByteLinkedList;
import lz77.util.CharLinkedList;
import lz77.util.LinkedListNode;
/**
 * Luokka, joka hoitaa pakattujen tiedostojen kirjoittamisen ja lukemisen
 * @author ossi
 *
 */
public class FileHandler {
	
	/**
	 * Kirjoittaa pakatun tiedoston
	 * @param filename Tiedoston nimi
	 * @param d Pakattu data
	 * @throws IOException
	 */
	public static void writeCompressedFile(String filename, CompressedData d) throws IOException {
		File outFile = new File(filename);
		
		DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(
				outFile)));

		LinkedListNode head = d.head();
		out.writeChar(d.getSize());
		while (head != null) {
			
			char len = ((CharLinkedList) head).value;
			out.writeChar(len);
			
			if (len != 0) {
				head = head.next();
				char pos = ((CharLinkedList) head).value;
				out.writeChar(pos);
			}
			
			head = head.next();
			byte data = ((ByteLinkedList) head).value;
			out.write(data);
			head = head.next();
		}
		out.close();
	}
	/**
	 * Lukee pakatun tiedoston
	 * @param filename Tiedoston nimi
	 * @return Tiedoston sisältö
	 * @throws IOException
	 */
	public static CompressedData readCompressedFile(String filename)
			throws IOException {
		File inFile = new File(filename);
		
		if (!inFile.exists()) {
			System.out.println("File " + filename + " doesn't exist!");
			return null;
		}
		
		DataInputStream in = new DataInputStream(new FileInputStream(inFile));
		char size = in.readChar();
		CompressedData c = new CompressedData(size);
		try {
			while (true) {
				char len = in.readChar();
				c.add(len);
				if (len != 0) {
					char pos = in.readChar();
					c.add(pos);
				}
				byte data = in.readByte();
				c.add(data);
			}
		} catch (EOFException e) {
		}
		in.close();
		return c;
	}
}
